<?php
/**
 * CN-FBA运单号异常（国内仓发fba仓）
 */
namespace App\Admin\Controllers\Delivery;

use App\Models\Amazon\FbaFulfillmentInventory;
use App\Models\Basics\SysPlatAccount;
use App\Models\Basics\AmazonCountry;
use App\Models\Basics\ExpressChannel;
use App\Models\Basics\ExpressCompany;
use App\Models\Basics\SysIArea;
use App\Models\Delivery\FBADelivery;
use App\Models\Sys\Logs;
use App\Util\User;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;

class FBATrackExController extends AdminController{

    protected $title = 'CN至FBA-运单号异常';

    protected $filters = [
        'start_date' => null,
        'end_date' => null,
        'delivery_no' => null,
        'account_id' => null,
        'area_id' => null,
        'country_id' => null,
        'seller_id' => null,
        'status' => null,
        'logistics_status' => null,
        'ex_desc' => null,
        'sku' => null,
    ];

    protected function grid()
    {
        $filtersField = array_keys($this->filters);
        $filters = $this->_getFilters($filtersField);
        $this->_initFilters($filters);
        $query = $this->_initQuery($filters);
        $paginator = $this->_paginator($query);
        $action = getAction($filtersField);
        $filtersBlade = [];
        $filtersBlade['start_date'] = $this->filters['start_date'];
        $filtersBlade['end_date'] = $this->filters['end_date'];
        $filtersBlade['delivery_no'] = $this->filters['delivery_no'];
        $filtersBlade['account_id'] = getOptions(SysPlatAccount::options(),$this->filters['account_id']);
        $filtersBlade['country_id'] = getOptions(AmazonCountry::options(),$this->filters['country_id']);
        $filtersBlade['area_id'] = getOptions(SysIArea::options(),$this->filters['area_id']);
        $filtersBlade['seller_id'] = getOptions(User::getSellerOptions(),$this->filters['seller_id']);
        $filtersBlade['status'] = getOptions(FBADelivery::$_status,$this->filters['status']);
        $filtersBlade['logistics_status'] = getOptions(FBADelivery::$_logisticsStatus,$this->filters['logistics_status']);
        $filtersBlade['sku'] = $this->filters['sku'];
        $downloadUrl = '/xqc/delivery/fba-track-ex-download?' . http_build_query(array_merge(Request::all(),['_export_' => true]));
        return view('delivery.fba-track-ex.index', compact('paginator','action','filtersBlade','downloadUrl'));
    }

    private function _getFilters($filtersField){
        $filters = [];
        foreach ($filtersField as $field){
            $filters[$field] = request($field);
        }
        return $filters;
    }

    private function _initFilters($filters){
        foreach ($filters as $field => $filter){
            $this->filters[$field] = $filter;
        }
    }

    private function _initQuery($filters){
        $query = FBADelivery::query()
            ->where('track_ex_status',1) //运单号异常
            ->orderBy('id', 'DESC');
        foreach ($filters as $field => $filter){
            if(!$filter)continue;
            if($field == 'start_date'){
                $query->where('delivered_at','>=',$filter.' 00:00:00');
            }
            if($field == 'end_date'){
                $query->where('delivered_at','<=',$filter.' 23:59:59');
            }
            if($field == 'sku'){
                $query->whereHas('detail.sku', function ($query) use($filter){
                    $query->where('psku_code', 'like', "%{$filter}%")
                        ->orWhere('psku_cn', 'like', "%{$filter}%");
                });
            }
            if(in_array($field,['delivery_no','country_id','account_id','area_id','seller_id','status','logistics_status'])){
                $query->where($field,$filter);
            }
        }
        return $query;
    }

    private function _paginator($query){
        return $query->paginate((int) (request("per_page",20)))->appends(Request::input());
    }

    protected function detail($id)
    {
        $delivery = FBADelivery::query()->findOrFail($id);
        $fulfillment = FbaFulfillmentInventory::query()
            ->where('fba_shipment_id',$delivery->delivery_no)
            ->orderBy('received_date', 'DESC')
            ->get();
        $logs = Logs::getLogs('os-out-delivery',$id);
        return view('delivery.fba-track-ex-detail.index', compact('id','delivery','fulfillment','logs'));
    }

    public function download(){
        $filtersField = array_keys($this->filters);
        $filters = $this->_getFilters($filtersField);
        $query = $this->_initQuery($filters);
        $this->_exeDownload($query);
    }

    private function _exeDownload($query){
        $head = ['发货单号','物流公司ID','物流渠道ID','销售员','发货账号','站点','发货国家','状态','备注','发货时间','物流公司','物流渠道','追踪号','发货公斤数','运费'];
        set_time_limit(0);
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="运单号异常.csv"',
        ]);
        $response->setCallback(function () use ($head, $query) {
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->orderBy('id','DESC')->chunk(500, function ($re) use ($fp){
                $data = self::getDownloadData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    public static function getDownloadData($re){
        foreach ($re as $row){
            $temp = [
                $row->delivery_no,
                $row->logistics->express_company_id ?? '',
                $row->logistics->express_channel_id ?? '',
                User::getUsernameById($row->seller_id),
                $row->account->account ?? '',
                $row->area->area ?? '',
                $row->country->country ?? '',
                FBADelivery::$_status[$row->status],
                $row->remarks,
                $row->delivered_at,
                ExpressCompany::getNameById($row->logistics->express_company_id ?? null),
                ExpressChannel::getNameById($row->logistics->express_channel_id ?? null),
                $row->logistics->tracking_no ?? '',
                $row->logistics->total_weight ?? '',
                $row->logistics->shipping_fee ?? '',
            ];
            yield $temp;
        }
    }
}
